
let Cell = require('./cell');
let Methods = require('./methods');

let qkBC = require('./qkBC');

function checkSelectedCells(selectedCells) {
    if(!selectedCells || selectedCells.length < 1){
        return null;
    }

    let map = {};
    selectedCells.forEach(cell=>{
        let maybeArr = cell.getMaybeArr();
        maybeArr.forEach(value=>{
            if(!map[value]){
                map[value] = 1;
            } else{
                map[value]++;
            }
        });
    });

    // 如果map中存在 某个key 为 value 的值为1,则此值为唯一解决
    for(let k in map){
        if(map[k] === 1){

            // 找到k在哪个cell中
            let value = Number(k);
            let targetCell = selectedCells.find(cell=>{
                return cell.getMaybeArr().indexOf(value) >= 0;
            });
            return {
                x:targetCell.rowIdx,
                y:targetCell.colIdx,
                value:value,
                type:Methods.UnitBC
            }
        }
    }
    return null;
}

/**
 * 唯余法
 * @param board
 */
function uniqueMod(boardInfo){

    let cells = [];
    let board = boardInfo.board;
    for(let i = 0; i < board.length; ++i){
        for (let j = 0; j < board[0].length; ++j){
            if(board[i][j] < 1){
                let cell = new Cell(i,j,boardInfo);
                cell.simplify();
                cells.push(cell);

                let result = cell.getResult();
                if(result){
                    return  result;
                }
            }
        }
    }

    // 上面没有找到解
    // 再使用 单元摒除法
    // 分别检查行 列 宫 的可能值中,是否存在唯一可能
    // 检查行
    for(let i = 0; i < board.length; ++i){
        let rowCells = cells.filter(cell=>{
            return cell.rowIdx === i;
        });
        let result = checkSelectedCells(rowCells);
        if(result){
            return  result;
        }
    }

    // 检查列
    for(let j = 0; j < board[0].length; ++j){
        let colCells = cells.filter(cell=>{
            return cell.colIdx === j;
        });
        let result = checkSelectedCells(colCells);
        if(result){
            return  result;
        }
    }

    // 检查宫
    //
    let lstGongCells = []; // 用于下一个阶段
    let gongCount = boardInfo.gongCount;
    let gongRowCount = boardInfo.gongRowCount;
    let gongColCount = boardInfo.gongColCount;
    for(let k = 0; k < gongCount; ++k){
        let startIds = boardInfo.getGongStartIdx(k);
        let minRowIdx = startIds.x;
        let maxRowIdx = startIds.x + gongRowCount - 1;
        let minColIdx = startIds.y;
        let maxColIdx = startIds.y + gongColCount - 1;
        let gongCells = cells.filter(cell=>{
            return cell.rowIdx >= minRowIdx && cell.rowIdx <= maxRowIdx &&
                   cell.colIdx >= minColIdx && cell.colIdx <= maxColIdx;
        });
        let result = checkSelectedCells(gongCells);
        if(result){
            return result;
        }

        lstGongCells.push(gongCells);
    }

    // console.log(`----------------剩余结构:`);
    // cells.forEach(cell=>{
    //     console.log(JSON.stringify(cell));
    // });

    //---------
    // console.log(`给出盘面.....`);
    // cells.forEach(cell=>{
    //     console.log(JSON.stringify(cell.getTipsObj()));
    // });

    console.log(`进行 qkBC 检查`);
    let result = qkBC(boardInfo,cells,lstGongCells);
    if(result){
        console.log(`qkBC result:${JSON.stringify(result)}`);

        // 检查所有的 cell,判断里面是否存在唯一值.
        // 如果存在,则给出唯一值 就是 提示结果.

    }

    return null;
}


let bTest = true;
if(bTest){

    // let initBoard = [
    //     [8,3,6, 4,9,2, 1,7,5],
    //     [5,9,7, 8,3,1, 2,6,4],
    //     [2,1,4, 7,5,6, 8,9,3],
    //
    //     [3,8,2, 9,7,4, 5,1,6],
    //     [7,4,9, 6,1,5, 3,8,2],
    //     [1,6,5, 3,2,8, 7,4,9],
    //
    //     [6,7,3, 5,8,9, 4,2,1],
    //     [9,2,8, 1,4,3, 6,5,7],
    //     [4,5,1, 2,6,7, 9,3,8],
    // ];

    // 验证 区域摒除法 的情况
    let initBoard = [
        [3,7,8, 0,0,9, 0,6,2],
        [9,5,4, 8,2,6, 7,3,1],
        [2,6,1, 0,7,3, 0,0,0],

        [0,0,2, 6,0,4, 9,7,0],
        [7,0,9, 2,3,0, 0,0,0],
        [0,0,0, 7,9,8, 0,2,0],

        [8,1,3, 9,0,2, 0,0,7],
        [0,2,7, 0,8,0, 0,0,0],
        [0,9,0, 0,0,7, 2,8,0],
    ];

    // let initBoard = [
    //     [3,7,8, 1,4,9, 5,6,2],
    //     [9,5,4, 8,2,6, 7,3,1],
    //     [2,6,1, 0,7,3, 0,0,0],
    //
    //     [1,0,2, 6,5,4, 9,7,0],
    //     [7,0,9, 2,3,1, 0,0,0],
    //     [5,0,6, 7,9,8, 1,2,0],
    //
    //     [8,1,3, 9,6,2, 4,5,7],
    //     [6,2,7, 4,8,5, 3,0,0],
    //     [4,9,5, 3,1,7, 2,8,0],
    // ];

    let BoardInfo = require('./boardInfo');
    let info = new BoardInfo(initBoard);
    console.log(uniqueMod(info));
}

module.exports = uniqueMod;
